#include <btl/Image/ImagePyramid.hpp>
#include <btl/Utility/OpenCVSupport.hpp>

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>

namespace btl
{
namespace image
{

template <class PixelType>
void halfScaleImageGeneric(const ImageRegion<const PixelType>& in, ImageRegion<PixelType>& out)
{
   assert(!in.null());
   assert(!out.null());

   const int toW = (in.width() + 1) / 2;
   const int toH = (in.height() + 1) / 2;

   cv::Mat from = cvUnsafeUnconstImage(in);
   cv::Mat to = cvImage(out);
   cv::pyrDown(from, to, cv::Size(toW, toH));
}

// implement a public non-templated interface so that OpenCV doesn't creep into the header
void halfScaleImage(const ImageRegion<const PixelGrey>& in, ImageRegion<PixelGrey>& out)
{
   halfScaleImageGeneric(in, out);
}

void halfScaleImage(const ImageRegion<const PixelRGB>& in, ImageRegion<PixelRGB>& out)
{
   halfScaleImageGeneric(in, out);
}

void halfScaleImage(const ImageRegion<const PixelFloat>& in, ImageRegion<PixelFloat>& out)
{
   halfScaleImageGeneric(in, out);
}

} // namespace image
} // namespace btl
